﻿using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.Runtime.Session;
using Abp.UI;
using SingleUserMall.Common;
using SingleUserMall.Items;
using SingleUserMall.Orders;
using SingleUserMall.Refunds.Form;
using SingleUserMall.Refunds.VO;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SingleUserMall.Refunds
{
    [AbpAuthorize]
    public class RefundAppService : SingleUserMallAppServiceBase, IRefundAppService
    {
        private readonly IRepository<Refund, long> _refundRepository;
        private readonly IRepository<OrderDetail, long> _orderDetailRepository;
        private readonly IRepository<RefundLog, long> _refundLogRepository;
        private readonly IRepository<ItemSpec, long> _itemSpecRepository;
        public RefundAppService(
            IRepository<Refund, long> refundRepository,
            IRepository<OrderDetail, long> orderDetailRepository,
            IRepository<RefundLog, long> refundLogRepository,
            IRepository<ItemSpec, long> itemSpecRepository
            )
        {
            _refundRepository = refundRepository;
            _orderDetailRepository = orderDetailRepository;
            _refundLogRepository = refundLogRepository;
            _itemSpecRepository = itemSpecRepository;
        }

        public async Task CancelRefundAsync(SingleId<long> form)
        {
            var userId = AbpSession.GetUserId();
            var refund = await _refundRepository.FirstOrDefaultAsync(form.Id);
            refund.Status = RefundStatus.Cancel;
            refund.CloseReason = "买家撤销申请";
            refund.FinishTime = DateTime.Now;
            await _refundLogRepository.InsertAsync(new RefundLog
            {
                RefundId = refund.Id,
                UserId = userId,
                Content = "买家撤销申请",
                IsSeller = true
            });
        }

        public async Task<RefundVO> GetRefundInfoAsync(OrderDetailForm form)
        {
            var refund = await _refundRepository.GetAll()
                .Where(x => x.OrderDetailId == form.OrderDetailId)
                .FirstOrDefaultAsync();
            return refund.ToVO<Refund, RefundVO>((r, vo) =>
            {
                vo.inOrder = r.Order;
                vo.inItem = r.OrderDetail.ItemSpec.Item;
                vo.inItemSpec = r.OrderDetail.ItemSpec;
                vo.inOrderDetail = r.OrderDetail;
            });
        }

        public async Task<OrderDetailMiniVO> GetRefundItemAsync(OrderDetailForm form)
        {
            var detail = await _orderDetailRepository.FirstOrDefaultAsync(form.OrderDetailId);
            return detail.ToVO<OrderDetail, OrderDetailMiniVO>((d, vo) =>
            {
                vo.inOrder = d.Order;
                vo.inItem = d.ItemSpec.Item;
                vo.inItemSpec = d.ItemSpec;
            });
        }

        public async Task<ListResultDto<RefundLogVO>> GetRefundLogsAsync(SingleId<long> form)
        {
            var query = _refundLogRepository.GetAll().Where(x => x.RefundId == form.Id)
                .OrderByDescending(x => x.CreationTime);
            return await query.ToListResultDtoAsync<RefundLog, RefundLogVO>();
        }

        public async Task<RefundVO> RefundAsync(RefundForm form)
        {
            var userId = AbpSession.GetUserId();
            if(_refundRepository.Count(x=> x.OrderId == form.OrderId && x.OrderDetailId == form.OrderDetailId && x.Status == RefundStatus.WaitAudit) > 0)
            {
                throw new UserFriendlyException("您已经有退款申请在审核中， 不能再次提交");
            }
            var refund = form.MapTo<Refund>();
            refund.RefundNo = Functions.NewOrderNo();
            refund.Status = RefundStatus.WaitAudit;
            var refundId = await _refundRepository.InsertAndGetIdAsync(refund);
            await CurrentUnitOfWork.SaveChangesAsync();
            refund = await _refundRepository.FirstOrDefaultAsync(refundId);
            await _refundLogRepository.InsertAsync(new RefundLog
            {
                RefundId = refund.Id,
                UserId = userId,
                Content = "买家提交退货申请",
                IsSeller = true
            });
            return refund.ToVO<Refund, RefundVO>((r, vo) =>
            {
                var orderDetail = _orderDetailRepository.FirstOrDefault(r.OrderDetailId);
                vo.inOrder = r.Order;
                vo.inItem = orderDetail.ItemSpec.Item;
                vo.inItemSpec = orderDetail.ItemSpec;
                vo.inOrderDetail = r.OrderDetail;
            });
        }
    }
}
